<template>
  <div v-show="!isEmpty" class="kgj-echarts" :class="{ flex: isCenter }" @mouseout="mouseLeave">
    <VChart
      :ref="(ref:any) => (chartsRef = ref)"
      class="echarts"
      :style="{ width: width, height: height }"
      :option="option"
      autoresize
      @legendselectchanged="legendChange"
      @click="$emit('click', $event)"
      @mouseout="mouseLeave"
    />
  </div>
  <div
    v-show="isEmpty"
    :style="{ width: width, height: height }"
    class="empty"
  >
    <KEmpty />
  </div>
</template>

<script setup lang="ts">
import { defineComponent, ref, watch, onMounted, onUpdated } from 'vue';
import china from './china.json';
import * as echarts from 'echarts';
import VChart from 'vue-echarts';
/**
 *@echarts
 */
defineComponent({ name: 'KgjEcharts' });

interface optionItem {
  grid?: object;
  legend?: object;
  tooltip?: object;
  color?: Array<string>;
  xAxis: object;
  yAxis: object;
  series: Array<any>;
}
interface Props {
  width?: string;
  height?: string;
  option: optionItem;
  enableClickLegend?: boolean; // 是否可以点击legend
  isFixed?: boolean; // legend是否有固定的，不能取消
  isEmpty?: boolean; // 是否无数据
  isCenter?: boolean; // 是否居中
  over?: boolean; // 是否通知鼠标进出事件
  showTool?: boolean; // 是否固定显示tooltip
  length?: number; // 数据长度，与showTool配合使用
  pieHighlight?: boolean; // 饼图是否默认高亮
  highlightIndex?: number; // 高亮索引
}
const props = withDefaults(defineProps<Props>(), {
  width: '100%',
  height: '100%',
  enableClickLegend: false,
  isFixed: false,
  isEmpty: false,
  isCenter: false,
  over: false,
  showTool: false,
  length: 0,
  pieHighlight: false,
  highlightIndex: 0
});

// emit
const emits = defineEmits(['click', 'leave', 'out', 'over']);

echarts.registerMap('china', china as any);

const chartsRef = ref();
let isInit = false;
const init = () => {
  // 加个定时器，转为异步处理，解决charts未初始化导致调用clear报错问题
  if (!isInit) {
    setTimeout(() => {
      if (!chartsRef.value) return;
      chartsRef.value.clear();
      chartsRef.value.setOption(props.option);
      isInit = true;
    }, 0);
  } else {
    if (!chartsRef.value) return (isInit = true);
    chartsRef.value.clear();
    chartsRef.value.setOption(props.option);
  }
};

let tempIndex = 0;
watch(
  () => props.option,
  (newData) => {
    if (newData) {
      init();
    }
  },
  {
    deep: true
  }
);

const legendChange = (params: any) => {
  let optionLegend = chartsRef.value.getOption();
  let legend = optionLegend.legend[0];
  if (props.isFixed) {
    legend.selected[legend.data[0]] = true;
  } else {
    const select_value = Object.values(params.selected);
    let n = 0;
    select_value.map(function (res) {
      if (!res) {
        n++;
      }
    });
    if (n === select_value.length || props.enableClickLegend) {
      legend.selected[params.name] = true;
    }
  }
  chartsRef.value.setOption(optionLegend);
};

// 索引初始化为最后一个数据的索引
const dataIndex = ref(0);
// 鼠标离开图表时，显示对应索引数据的tooltip
function mouseLeave() {
  if (props.showTool) {
    chartsRef.value.chart.dispatchAction({
      type: 'showTip',
      seriesIndex: 1,
      dataIndex: dataIndex.value
    });
  }
}

const selectHighlight = (index: number) => {
  chartsRef.value.chart.dispatchAction({
    type: 'downplay',
    dataIndex: tempIndex
  });
  chartsRef.value.chart.dispatchAction({
    type: 'highlight',
    dataIndex: index
  });
  tempIndex = index;
};

onMounted(() => {
  if (props.pieHighlight) {
    // 饼图默认高亮第一个数据
    setTimeout(() => {
      chartsRef.value.chart.dispatchAction({
        type: 'highlight',
        dataIndex: props.highlightIndex
      });
    }, 500);
    tempIndex = props.highlightIndex;

    // 鼠标移入时取消高亮之前的数据，高亮当前数据，并将当前数据索引赋值给dataIndex
    chartsRef.value.chart.on('mouseover', (data: any) => {
      chartsRef.value.chart.dispatchAction({
        type: 'downplay',
        dataIndex: tempIndex
      });
      chartsRef.value.chart.dispatchAction({
        type: 'highlight',
        dataIndex: data.dataIndex
      });
      tempIndex = data.dataIndex;
    });
  }

  // 图表初始化后就显示最新数据的tooltip
  if (props.showTool) {
    setTimeout(() => {
      chartsRef.value?.chart?.dispatchAction({
        type: 'showTip',
        seriesIndex: 1,
        dataIndex: props.length
      });
    }, 500);
  }
  chartsRef.value?.chart?.on('mouseover', function (val: any) {
    if (props.over) {
      emits('over', val);
    }
    // 索引指向鼠标离开前指向的最后一个数据
    if (props.showTool) {
      dataIndex.value = val.dataIndex;
    }
  });
  chartsRef.value?.chart?.on('mouseout', function () {
    if (props.over) {
      emits('leave'); // deprepated
      emits('out'); // over对应out
    }
  });
  chartsRef.value?.chart?.on('mousemove', function (val: any) {
    // 索引跟随鼠标指向的数据
    if (props.showTool) {
      dataIndex.value = val.dataIndex;
    }
  });
});

onUpdated(() => {
  if (props.showTool) {
    setTimeout(() => {
      chartsRef.value.chart.dispatchAction({
        type: 'showTip',
        seriesIndex: 1,
        dataIndex: props.length
      });
    }, 500);
  }
  dataIndex.value = props.length;
});

defineExpose({
  chartsRef,
  selectHighlight
});
</script>

<style lang="scss" scoped>
.kgj-echarts {
  width: 100%;
  height: 100%;

  .echarts {
    position: relative;
    width: 100%;
    height: 100%;

    :deep(.chart-tooltip) {
      min-width: 163px;

      &.tree-map {
        min-width: 77px;
      }

      &.line {
        max-width: 220px;
      }

      &.line-bar {
        max-width: 176px;
      }

      .title {
        overflow: hidden;
        font-family: 'PingFang SC', sans-serif;
        font-size: 13px;
        font-style: normal;
        font-weight: 400;
        line-height: 20px;
        color: #fff;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      .subtitle {
        margin-bottom: 8px;
        font-family: number, sans-serif;
        font-size: 13px;
        font-style: normal;
        font-weight: 500;
        line-height: 20px;
        color: #c9cdd4;

        &.no-number {
          font-family: 'PingFang SC', sans-serif;
        }

        &.text-1 {
          color: #fff;
        }
      }

      .row {
        display: flex;
        align-items: center;
        margin-top: 4px;
        color: #fff;

        .sample {
          width: 8px;
          height: 8px;
          margin-right: 8px;
          border-radius: 50%;
        }

        .name {
          font-family: 'PingFang SC', sans-serif;
          font-size: 14px;
          font-style: normal;
          font-weight: 400;
          line-height: 22px;
        }

        .value {
          flex: 1;
          font-size: 0;
          text-align: right;
          vertical-align: middle;

          .value-inner {
            display: flex;
            flex-direction: row-reverse;
            align-items: baseline;
            width: 100%;
          }
        }

        .number,
        .unit {
          font-family: number, sans-serif;
          font-size: 14px;
          font-style: normal;
          font-weight: 500;
          line-height: 20px;
          color: #fff;
        }

        .unit {
          font-family: 'PingFang SC', sans-serif;
          font-size: 12px;
        }
      }
    }
  }
}

.empty {
  display: flex;
  align-items: center;
  justify-content: center;
}

.flex {
  display: flex;
  justify-content: center;
}
</style>
